﻿Imports System
Imports System.ComponentModel
Imports System.Reflection

Public Class Utils

  Public Shared Function EnumGetDescription(ByVal en As [Enum]) As String
    Dim type As Type = en.GetType
    Dim memInfo() As MemberInfo = type.GetMember(en.ToString)
    If ((Not (memInfo) Is Nothing) AndAlso (memInfo.Length > 0)) Then
      Dim attrs() As Object = memInfo(0).GetCustomAttributes(GetType(DescriptionAttribute), False)
      If ((Not (attrs) Is Nothing) AndAlso (attrs.Length > 0)) Then
        Return CType(attrs(0), DescriptionAttribute).Description
      End If
    End If
    Return en.ToString
  End Function


  Public Shared Function FindControlRecursive(ByVal pRoot As Control, ByVal Id As String) As Control
    Try
      If pRoot.ID = Id Then
        Return pRoot
      End If
      For Each unControl In pRoot.Controls
        Dim controlEncontrado = FindControlRecursive(unControl, Id)
        If controlEncontrado IsNot Nothing Then
          Return controlEncontrado
        End If
      Next
      Return Nothing
    Catch ex As Exception
      Throw ex
    End Try
  End Function

  Public Shared Function GetCuitFormateado(ByVal pCuit As String) As String
    Dim strCuil1 As String = ""
    Dim strCuil2 As String = ""
    Dim strCuil3 As String = ""
    Dim cuil As String = pCuit
    Try
      If cuil.Length >= 11 Then
        strCuil1 = cuil.Substring(0, 2)
        strCuil2 = cuil.Substring(2, cuil.Length - 3)
        strCuil3 = cuil.Substring(cuil.Length - 1, 1)
        Return strCuil1 & "-" & strCuil2 & "-" & strCuil3
      Else
        Return cuil
      End If
    Catch ex As Exception
      Throw New Exception("Error en el formateo del CUIT")
    End Try

  End Function


  ''' <summary>
  ''' Procedimiento que elimina el cache de la página solicitada
  ''' </summary>
  ''' <param name="pPage"></param>
  ''' <remarks></remarks>
  Public Shared Sub ClearCache(ByRef pPage As Page)
    Try
      pPage.Response.Clear()
      pPage.Response.Expires = -1
      pPage.Response.CacheControl = "private"
    Catch ex As Exception
    End Try
  End Sub

  ''' <summary>
  ''' Carga un control DropDownList a partir de un origen de
  ''' datos. 
  ''' </summary>
  ''' <param name="pDropDownList"></param>
  ''' <param name="pDataSource"></param>
  ''' <param name="pDataTextField"></param>
  ''' <param name="pDataValueField"></param>
  ''' <remarks></remarks>
  Public Shared Sub LoadDropDownList(ByRef pDropDownList As DropDownList, _
                                    ByVal pDataSource As Object, _
                                    ByVal pDataTextField As String, _
                                    ByVal pDataValueField As String)

    Utils.LoadDropDownList(pDropDownList, pDataSource, _
                           pDataTextField, pDataValueField, True)

  End Sub


  ''' <summary>
  ''' Carga un control DropDownList a partir de un origen de
  ''' datos. 
  ''' </summary>
  ''' <param name="pDropDownList"></param>
  ''' <param name="pDataSource"></param>
  ''' <param name="pDataTextField"></param>
  ''' <param name="pDataValueField"></param>
  ''' <param name="pAddInitialItem">Especifica si se deberá crear un ítem inicial, que no pertenezca al origen de datos. True por defecto.</param>
  ''' <param name="pInitialText">Texto del ítem inicial. "(Todos)" por defecto.</param>
  ''' <remarks></remarks>
  Public Shared Sub LoadDropDownList(ByRef pDropDownList As DropDownList, _
                                    ByVal pDataSource As Object, _
                                    ByVal pDataTextField As String, _
                                    ByVal pDataValueField As String, _
                                    ByVal pAddInitialItem As Boolean, _
                                    Optional ByVal pInitialText As String = "- Todos -")

    pDropDownList.DataTextField = pDataTextField
    pDropDownList.DataValueField = pDataValueField
    pDropDownList.DataSource = pDataSource
    pDropDownList.DataBind()

    If pAddInitialItem Then
      pDropDownList.Items.Insert(0, pInitialText)
    End If

  End Sub

#Region "Enumerations"
  Public Enum DayHoursActionEnum
    RemoveDayHours
    AddDayHours
  End Enum
#End Region

#Region "Nullables"
  ''' <summary>
  ''' Returns Nothing if can't returns an integer value.
  ''' </summary>
  ''' <param name="pValue"></param>
  ''' <returns></returns>
  ''' <remarks></remarks>
  Public Shared Function ParseNullableInt(ByVal pValue As String) As Nullable(Of Integer)
    Dim tmpValue As Integer

    If Not Int32.TryParse(pValue, tmpValue) Then
      Return Nothing
    Else
      'Return IIf(tmpValue = 0, Nothing, tmpValue)
      Return tmpValue
    End If
  End Function

  ''' <summary>
  ''' Returns Nothing if can't returns a Single value.
  ''' </summary>
  ''' <param name="pValue"></param>
  ''' <returns></returns>
  ''' <remarks></remarks>
  Public Shared Function ParseNullableSingle(ByVal pValue As String) As Nullable(Of Single)
    Dim tmpValue As Single

    If Not Single.TryParse(pValue, tmpValue) Then
      Return Nothing
    Else
      Return tmpValue
    End If
  End Function

  ''' <summary>
  ''' Returns Nothing if can't returns a double value.
  ''' </summary>
  ''' <param name="pValue"></param>
  ''' <returns></returns>
  ''' <remarks></remarks>
  Public Shared Function ParseNullableDouble(ByVal pValue As String) As Nullable(Of Double)
    Dim tmpValue As Double

    If Not Double.TryParse(pValue, tmpValue) Then
      Return Nothing
    Else
      Return tmpValue
    End If
  End Function

  ''' <summary>
  ''' Returns Nothing if can't returns a decimal value.
  ''' </summary>
  ''' <param name="pValue"></param>
  ''' <returns></returns>
  ''' <remarks></remarks>
  Public Shared Function ParseNullableDecimal(ByVal pValue As String) As Nullable(Of Decimal)
    Dim tmpValue As Decimal

    If Not Decimal.TryParse(pValue, tmpValue) Then
      Return Nothing
    Else
      Return tmpValue
    End If
  End Function

  ''' <summary>
  ''' Returns nothing if pValue is Datetime MinValue or MaxValue. 
  ''' Also remove or added time value 
  ''' </summary>
  ''' <param name="pValue"></param>
  ''' <param name="pAction"></param>
  ''' <returns></returns>
  ''' <remarks></remarks>
  Public Shared Function ParseNullableDatetime(ByVal pValue As DateTime, ByVal pAction As DayHoursActionEnum) As Nullable(Of DateTime)
    Dim datRetValue As DateTime

    If pValue = Nothing OrElse pValue = DateTime.MinValue Or pValue = DateTime.MaxValue Then
      Return Nothing
    End If

    'datRetValue = pValue.AddHours(pValue.Hour * -1).AddMinutes(pValue.Minute * -1).AddSeconds(pValue.Second * -1)

    If pAction = DayHoursActionEnum.AddDayHours Then
      Return New DateTime(pValue.Year, pValue.Month, pValue.Day, 23, 59, 59, 998)
    Else
      Return New DateTime(pValue.Year, pValue.Month, pValue.Day, 0, 0, 0, 0)
    End If

  End Function

  Public Shared Function ParseNullableDatetime(ByVal pValue As DateTime) As Nullable(Of DateTime)
    If pValue = Nothing OrElse pValue = DateTime.MinValue Or pValue = DateTime.MaxValue Then
      Return Nothing
    Else
      Return pValue
    End If
  End Function


  ''' <summary>
  ''' Return Nothing if can't returns a Guid value.
  ''' </summary>
  ''' <param name="pValue"></param>
  ''' <returns></returns>
  ''' <remarks></remarks>
  Public Shared Function ParseNullableGuid(ByVal pValue As String) As Nullable(Of Guid)
    Dim guiRetVal As Guid
    Try
      guiRetVal = New Guid(pValue)
      Return guiRetVal
    Catch ex As Exception
      Return Nothing
    End Try
  End Function

  ''' <summary>
  ''' Returns Nothing if can't returns a byte value.
  ''' </summary>
  ''' <param name="pValue"></param>
  ''' <returns></returns>
  ''' <remarks></remarks>
  Public Shared Function ParseNullableByte(ByVal pValue As String) As Nullable(Of Byte)
    Dim tmpValue As Byte

    If Not Byte.TryParse(pValue, tmpValue) Then
      Return Nothing
    Else
      Return tmpValue
    End If
  End Function
#End Region



#Region "################ Funciones varias para setear JavaScript desde el servidor ################"
  ' Muestra un mensaje tipo MsgBox
  Public Shared Sub ShowMessage(ByVal Message As String, ByVal Pagina As Page)
    EjecutarScript("alert(""" & Message & """);", Pagina)
  End Sub

  'Muestra un mensaje en una ventana a traves de un javascript que se registra
  'al recargarse la pagina.
  Public Shared Sub MostrarVentanaAlerta(ByVal Mensaje As String, ByVal Pagina As Page)
    Try
      ShowMessage(Mensaje, Pagina)
    Catch ex As Exception
      Throw ex
    End Try
  End Sub


  ''' <summary>
  ''' Este metodo ejecuta un codigo JS al cargar una pagina del lado del cliente.
  ''' </summary>
  ''' <param name="CodigoScript">Codigo JS a ser ejecutado en el cliente.</param>
  ''' <param name="Pagina">Referencia al objeto pagina donde se quiere registrar el script. Por lo general solo poner "Me".</param>
  ''' <remarks>Usar este metodo SIEMPRE para lanzar scripts en el cliente para evitar key's duplicadas.</remarks>
  Public Shared Sub EjecutarScript(ByVal CodigoScript As String, ByVal Pagina As Page)
    Try
      Pagina.ClientScript.RegisterStartupScript(Pagina.GetType, GetUniqueKeyStartupScript(Pagina), CodigoScript, True)
    Catch ex As Exception
      Throw ex
    End Try
  End Sub


  ''' <summary>
  ''' Inserta codigo JavaScript en la pagina devuelta al cliente.
  ''' </summary>
  ''' <param name="CodigoScript">Codigo JS a ser ejecutado en el cliente.</param>
  ''' <param name="Pagina">Referencia al objeto pagina donde se quiere registrar el script. Por lo general solo poner "Me".</param>
  ''' <remarks>Usar este metodo SIEMPRE para enviar scripts al cliente para evitar key's duplicadas.</remarks>
  Public Shared Sub RegistrarScript(ByVal CodigoScript As String, ByVal Pagina As Page)
    Try
      Pagina.ClientScript.RegisterClientScriptBlock(Pagina.GetType, GetUniqueKeyScriptBlock(Pagina), CodigoScript, True)
    Catch ex As Exception
      Throw ex
    End Try
  End Sub

  ''' <summary>
  ''' Genera una clave unica para registrar un script al inicio de la pagina.
  ''' </summary>
  ''' <param name="Pagina">referencia a la pagina que se le quiere agregar el script</param>
  ''' <returns>Key unica del script</returns>
  ''' <remarks>Utilizar este metodo SIEMPRE para generar las keys a utilizar para registrar StartupScripts  en el cliente.</remarks>
  Public Shared Function GetUniqueKeyStartupScript(ByVal Pagina As Page) As String
    Dim generator As Random
    Dim pKey As String
    Try
      generator = New Random
      pKey = generator.Next(0, 999999)
      If Not Pagina.ClientScript.IsStartupScriptRegistered(Pagina.GetType, pKey) Then
        Return pKey
      Else
        Return GetUniqueKeyStartupScript(Pagina)
      End If
    Catch ex As Exception
      Throw ex
    Finally
      generator = Nothing
    End Try
  End Function
  ''' <summary>
  ''' Genera una clave unica para registrar un script al inicio de la pagina.
  ''' </summary>
  ''' <param name="Pagina">referencia a la pagina que se le quiere agregar el script</param>
  ''' <returns>Key unica del script</returns>
  ''' <remarks>Utilizar este metodo SIEMPRE para generar las keys a utilizar para registrar StartupScripts  en el cliente.</remarks>
  Public Shared Function GetUniqueKeyScriptBlock(ByVal Pagina As Page) As String
    Dim generator As Random
    Dim pKey As String
    Try
      generator = New Random
      pKey = generator.Next(0, 999999)
      If Not Pagina.ClientScript.IsClientScriptBlockRegistered(Pagina.GetType, pKey) Then
        Return pKey
      Else
        Return GetUniqueKeyScriptBlock(Pagina)
      End If
    Catch ex As Exception
      Throw ex
    Finally
      generator = Nothing
    End Try
  End Function


  'Esta pagina se encarga de actualizar la pagina padre.
  'Se tiene que utilizar cuando la ventana actual se abre utilizando
  'desde un formulario padre desde javascript "window.open(...)"
  Public Shared Sub ActualizarPaginaPadre(ByVal Pagina As Page)
    Try
      EjecutarScript("window.opener.document.forms(0).submit();", Pagina)
    Catch ex As Exception
      Throw ex
    End Try
  End Sub

  ''' <summary>
  ''' Setea el foco de la pagina en un control
  ''' </summary>
  ''' <param name="Pagina">Pagina donde se encuentra el control</param>
  ''' <param name="Control">Control sobre el que se desea setear el foco</param>
  ''' <remarks></remarks>
  Public Shared Sub ControlSetFocus(ByVal Pagina As Page, ByVal Control As String)
    EjecutarScript("document.getElementById('" & Control & "').focus();", Pagina)
  End Sub

#End Region
End Class

